/**
 * 认证服务
 * 作者：GodMainCode
 * 创建时间：2024-01-17
 * 修改时间：2024-01-17
 * 修改人：GodMainCode
 */

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../user/user.service';
import { LoginDto } from './dto/login.dto';
import { RegisterDto } from './dto/register.dto';
import * as bcrypt from 'bcryptjs';

@Injectable()
export class AuthService {
  constructor(
    private readonly userService: UserService,
    private readonly jwtService: JwtService,
  ) {}

  /**
   * 用户登录
   * @param loginDto 登录信息
   * @returns 登录成功的token信息
   */
  async login(loginDto: LoginDto) {
    const user = await this.validateUser(loginDto.username, loginDto.password);
    
    const payload = { 
      sub: user.id, 
      username: user.username 
    };

    return {
      access_token: this.jwtService.sign(payload),
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
      },
    };
  }

  /**
   * 用户注册
   * @param registerDto 注册信息
   * @returns 注册成功的用户信息
   */
  async register(registerDto: RegisterDto) {
    // 检查用户是否已存在
    const existingUser = await this.userService.findByUsername(registerDto.username);
    if (existingUser) {
      throw new UnauthorizedException('用户名已存在');
    }

    // 密码加密
    const hashedPassword = await bcrypt.hash(registerDto.password, 10);

    // 创建新用户
    const newUser = await this.userService.create({
      ...registerDto,
      password: hashedPassword,
    });

    return {
      id: newUser.id,
      username: newUser.username,
      email: newUser.email,
    };
  }

  /**
   * 验证用户
   * @param username 用户名
   * @param password 密码
   * @returns 验证通过的用户信息
   */
  public async validateUser(username: string, password: string) {
    const user = await this.userService.findByUsername(username);
    if (!user) {
      throw new UnauthorizedException('用户名或密码错误');
    }

    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      throw new UnauthorizedException('用户名或密码错误');
    }

    return user;
  }
} 